package com.ruicar.afs.cloud.finance.mq.receiver.basic.processor;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.common.modules.contract.enums.FundLineEnum;
import com.ruicar.afs.cloud.common.modules.contract.enums.ReceiptOperateTypeEnums;
import com.ruicar.afs.cloud.common.modules.contract.enums.ReturnCodeEnum;
import com.ruicar.afs.cloud.common.modules.contract.enums.UnusedFundsStatusEnums;
import com.ruicar.afs.cloud.common.mq.finance.debit.dto.DebitSuccessDataDto;
import com.ruicar.afs.cloud.common.mq.finance.debit.dto.StartReceiptHandleDto;
import com.ruicar.afs.cloud.common.mq.rabbit.listener.AfsMqBizProcessor;
import com.ruicar.afs.cloud.common.mq.rabbit.message.AfsTransEntity;
import com.ruicar.afs.cloud.common.mq.rabbit.message.MqTransCode;
import com.ruicar.afs.cloud.finance.common.entity.*;
import com.ruicar.afs.cloud.finance.common.service.*;
import com.ruicar.afs.cloud.finance.mq.sender.ReceiptSender;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 * <p>Description: </p>
 *
 * @author ZC.GUO
 * @version 1.0
 * @date create on 2020-07-01 19:29
 */
@Slf4j
@Component
@AllArgsConstructor
@ConditionalOnProperty(prefix = "com.ruicar.afs.cloud.mq.rabbit",name="enable")
public class DebitSuccessProcessor implements AfsMqBizProcessor<DebitSuccessDataDto> {

    private final FinanceVirtualAccountService financeVirtualAccountService;
    private final FinanceCustUnusedFundsService financeCustUnusedFundsService;
    private final FinanceReceiptOperateService financeReceiptOperateService;
    private final FinanceTransLineService financeTransLineService;
    private final FinanceUnusedFundsHistoryService financeUnusedFundsHistoryService;
    private final ReceiptSender receiptSender;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean processMessage(DebitSuccessDataDto entity) throws Exception {
        return this.transData(entity);
    }

    @Override
    public MqTransCode getCode() {
        return MqTransCode.AFS_CONTRACT_BASIC_FINANCE_CONTRACT_ARRIVE_SUCCESS;
    }

    private boolean transData(DebitSuccessDataDto debitSuccessDataDto){

        /**  客户虚拟账户信息 by ZC.GUO  **/
        FinanceVirtualAccount financeVirtualAccount = this.handleVirtualAccount(debitSuccessDataDto);
        log.info("客户虚拟账户信息更新完成，客户号{}",debitSuccessDataDto.getCustNo());
        /**  当前待分配款项 by ZC.GUO  **/
        FinanceCustUnusedFunds financeCustUnusedFunds = this.handleCustUnusedFunds(debitSuccessDataDto,financeVirtualAccount);
        log.info("当前待分配款项新增完成，客户号{}",debitSuccessDataDto.getCustNo());
        /**  账户余额分配流水 by ZC.GUO  **/
        this.handleUnusedFundsHistory(debitSuccessDataDto,financeVirtualAccount);
        log.info("账户余额分配流水新增完成，客户号{}",debitSuccessDataDto.getCustNo());
        /**  业务操作记录 by ZC.GUO  **/
        FinanceTransLine financeTransLine = this.handleTransLine(debitSuccessDataDto);
        log.info("业务操作记录新增完成，客户号{}",debitSuccessDataDto.getCustNo());
        /**  来款操作记录 by ZC.GUO  **/
        FinanceReceiptOperate financeReceiptOperate = this.handleReceiptOperate(debitSuccessDataDto,financeTransLine);
        log.info("来款操作记录新增完成，客户号{}",debitSuccessDataDto.getCustNo());

        /**  给basic服务发送指令，进行收据处理 by ZC.GUO  **/
        List<Long> receiptIdList = new ArrayList<>();
        receiptIdList.add(financeCustUnusedFunds.getFundId());

        AfsTransEntity<StartReceiptHandleDto> entity = new AfsTransEntity<>();
        StartReceiptHandleDto startReceiptHandleDto = new StartReceiptHandleDto();
        startReceiptHandleDto.setContractNo(debitSuccessDataDto.getContractNo());
        startReceiptHandleDto.setAccountId(financeVirtualAccount.getId());
        startReceiptHandleDto.setIdList(receiptIdList);
        startReceiptHandleDto.setOperator(debitSuccessDataDto.getOperator());
        entity.setData(startReceiptHandleDto);
        entity.setTransCode(MqTransCode.AFS_CONTRACT_FINANCE_BASIC_CONTRACT_START_RECEIPTHANDLE);

        financeCustUnusedFunds.setStatus(UnusedFundsStatusEnums.locked);
        financeCustUnusedFundsService.updateById(financeCustUnusedFunds);

        receiptSender.sendReceiptDealOrder(entity);


        return true;
    }

    private void handleUnusedFundsHistory(DebitSuccessDataDto entity, FinanceVirtualAccount virtualAccount){
        /**  非对公结算类型的撤销 by ZC.GUO  **/
        FinanceUnusedFundsHistory unusedFundsHistory = new FinanceUnusedFundsHistory();
        unusedFundsHistory.setAccountId(virtualAccount.getId());
        unusedFundsHistory.setContractNo(entity.getContractNo());
        unusedFundsHistory.setFundsType(FundLineEnum.credit);
        unusedFundsHistory.setFundId(entity.getFundId());
        unusedFundsHistory.setAmount(entity.getAmount());
        financeUnusedFundsHistoryService.save(unusedFundsHistory);
    }

    /**
     * 新增或更新客户虚拟账户信息
     * @author ZC.GUO
     * @param
     * @return
     */
    private FinanceVirtualAccount handleVirtualAccount(DebitSuccessDataDto debitSuccessDataDto){
        FinanceVirtualAccount financeVirtualAccount = financeVirtualAccountService.getOne(Wrappers.<FinanceVirtualAccount>query().lambda()
                .eq(FinanceVirtualAccount::getCustNo,debitSuccessDataDto.getCustNo())
        );
        if (financeVirtualAccount == null){
            financeVirtualAccount = new FinanceVirtualAccount();
            financeVirtualAccount.setCustNo(debitSuccessDataDto.getCustNo());
            financeVirtualAccount.setTotalAmt(BigDecimal.ZERO);
            financeVirtualAccount.setUsedAmt(BigDecimal.ZERO);
            financeVirtualAccount.setUnUsedAmt(BigDecimal.ZERO);
            financeVirtualAccount.setCancelAmt(BigDecimal.ZERO);
            financeVirtualAccount.setReturnAmt(BigDecimal.ZERO);
            financeVirtualAccount.setRevision(BigDecimal.ZERO.longValue());
            financeVirtualAccountService.save(financeVirtualAccount);
        }
        financeVirtualAccount.setTotalAmt(financeVirtualAccount.getTotalAmt().add(debitSuccessDataDto.getAmount()));
        financeVirtualAccount.setUnUsedAmt(financeVirtualAccount.getUnUsedAmt().add(debitSuccessDataDto.getAmount()));
        financeVirtualAccountService.updateById(financeVirtualAccount);
        return  financeVirtualAccount;
    }

    /**
     * 新增当前待分配款项
     * @author ZC.GUO
     * @param
     * @return
     */
    private FinanceCustUnusedFunds handleCustUnusedFunds(DebitSuccessDataDto debitSuccessDataDto,FinanceVirtualAccount financeVirtualAccount){
        FinanceCustUnusedFunds financeCustUnusedFunds = new FinanceCustUnusedFunds();
        financeCustUnusedFunds.setAccountId(financeVirtualAccount.getId());
        financeCustUnusedFunds.setFundsType(debitSuccessDataDto.getFundsType());
        financeCustUnusedFunds.setFundId(debitSuccessDataDto.getFundId());
        financeCustUnusedFunds.setAmount(debitSuccessDataDto.getAmount());
        financeCustUnusedFunds.setStatus(UnusedFundsStatusEnums.mayuse);
        financeCustUnusedFunds.setContractNo(debitSuccessDataDto.getContractNo());
        financeCustUnusedFunds.setRevision(BigDecimal.ZERO.longValue());
        financeCustUnusedFundsService.save(financeCustUnusedFunds);
        return  financeCustUnusedFunds;
    }

    /**
     * 新增来款操作记录
     * @author ZC.GUO
     * @param
     * @return
     */
    private FinanceReceiptOperate handleReceiptOperate(DebitSuccessDataDto debitSuccessDataDto,FinanceTransLine financeTransLine){
        FinanceReceiptOperate financeReceiptOperate = new FinanceReceiptOperate();
        financeReceiptOperate.setTransId(financeTransLine.getId());
        financeReceiptOperate.setFundsType(debitSuccessDataDto.getReceiptSourceType());
        financeReceiptOperate.setFundsId(debitSuccessDataDto.getFundId());
        financeReceiptOperate.setTime(Calendar.getInstance().getTime());
        financeReceiptOperate.setType(ReceiptOperateTypeEnums.arrive);
        financeReceiptOperate.setAmount(debitSuccessDataDto.getAmount());
        financeReceiptOperateService.save(financeReceiptOperate);
        return  financeReceiptOperate;
    }

    /**
     * 新增业务操作记录
     * @author ZC.GUO
     * @param
     * @return
     */
    private FinanceTransLine handleTransLine(DebitSuccessDataDto debitSuccessDataDto){
        FinanceTransLine financeTransLine = new FinanceTransLine();
        financeTransLine.setCustNo(debitSuccessDataDto.getCustNo());
        financeTransLine.setOperateType(debitSuccessDataDto.getOperateType());
        financeTransLine.setOperator(debitSuccessDataDto.getOperator());
        financeTransLine.setOperateResult(ReturnCodeEnum.success);
        financeTransLine.setOperateTime(Calendar.getInstance().getTime());
        financeTransLineService.save(financeTransLine);
        return  financeTransLine;
    }
}
